home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
edit
/
xvisrc.zip
/
STARTUP.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-07-28
|
10KB
|
409 lines
/* Copyright (c) 1990,1991,1992 Chris and John Downey */
#ifndef lint
static char *sccsid = "@(#)startup.c 2.3 (Chris & John Downey) 9/4/92";
#endif
/***
* program name:
xvi
* function:
PD version of UNIX "vi" editor, with extensions.
* module name:
main.c
* module function:
Entry point for xvi; setup, argument parsing and signal handling.
* history:
STEVIE - ST Editor for VI Enthusiasts, Version 3.10
Originally by Tim Thompson (twitch!tjt)
Extensive modifications by Tony Andrews (onecom!wldrdg!tony)
Heavily modified by Chris & John Downey
***/
#include "xvi.h"
/*
* References to the current cursor position, and the window
* and buffer into which it references. These make the code a
* lot simpler, but we have to be a bit careful to update them
* whenever necessary.
*/
Buffer *curbuf;
Xviwin *curwin;
/*
* Global variables.
*/
state_t State = NORMAL; /* This is the current state of the command */
/* interpreter. */
unsigned echo; /*
* bitmap controlling the verbosity of
* screen output (see xvi.h for details).
*/
int indentchars; /* number of chars indented on current line */
volatile unsigned char
kbdintr; /*
* global flag set when a keyboard interrupt
* is received
*/
bool_t imessage; /*
* global flag to indicate whether we should
* display the "Interrupted" message
*/
/*
* Internal routines.
*/
static void usage P((void));
Xviwin *
xvi_startup(vs, argc, argv, envp)
VirtScr *vs;
int argc;
char *argv[];
char *envp; /* init string from the environment */
{
char *tag = NULL; /* tag from command line */
char *pat = NULL; /* pattern from command line */
long line = -1; /* line number from command line */
char **files;
int numfiles = 0;
int count;
char *env;
ignore_signals();
/*
* Initialise parameter module.
*/
init_params();
/*
* Initialise yank/put module.
*/
init_yankput();
/*
* The critical path this code has to follow is quite tricky.
* We can't really run the "env" string until after we've set
* up the first screen window because we don't know what the
* commands in "env" might do: they might, for all we know,
* want to display something. And we can't set up the first
* screen window until we've set up the terminal interface.
*
* Also, we can't read the command line arguments until after
* we've run the "env" string because a "-s param=value" argument
* should override any setting of that parameter in the environment.
*
* All this means that the usage() function, which tells the
* user that the command line syntax was wrong, can only be
* called after the display interface has already been set up,
* which means we must be in visual mode. So usage() has to
* switch back to system mode (otherwise, on systems where
* sys_startv() & sys_endv() switch display pages,
* the user will never see the output of usage()). So ...
*/
/*
* Set up the first buffer and screen window.
* Must call sys_init first.
*/
curbuf = new_buffer();
if (curbuf == NULL) {
sys_endv();
(void) fputs("Can't allocate buffer memory.\n", stderr);
sys_exit(2);
}
curwin = init_window(vs);
if (curwin == NULL) {
sys_endv();
(void) fputs("Can't allocate buffer memory.\n", stderr);
sys_exit(2);
}
/*
* Connect the two together.
*/
map_window_onto_buffer(curwin, curbuf);
init_sline(curwin);
/*
* Save a copy of the passed environment string in case it was
* obtained from getenv(), so that the subsequent call we make
* to get the SHELL parameter value does not overwrite it.
*/
if (envp != NULL) {
env = strsave(envp);
} else {
env = NULL;
}
/*
* Try to obtain a value for the "shell" parameter from the
* environment variable SHELL. If this is NULL, do not override
* any existing value. The system interface code (sys_init()) is
* free to set up a default value, and the initialisation string
* in the next part of the startup is free to override both that
* value and the one from the environment.
*/
{
char *sh;
sh = getenv("SHELL");
if (sh != NULL) {
set_param(P_shell, sh);
}
}
/*
* Run any initialisation string passed to us.
*
* We can't really do this until we have set up the terminal
* because we don't know what the initialisation string might do.
*/
if (env != NULL) {
register char *ep;
register bool_t escaped = FALSE;
/*
* Commands in the initialization string can be
* separated by '|' (or '\n'), but a literal '|' or
* '\n' can be escaped by a preceding '\\', so we have
* to process the string, looking for all three
* characters.
*/
for (ep = env; *ep;) {
switch (*ep++) {
case '\\':
escaped = TRUE;
continue;
case '|':
case '\n':
if (escaped) {
register char *s, *d;
for (d = (s = --ep) - 1; (*d++ = *s++) != '\0'; )
;
} else {
ep[-1] = '\0';
do_colon(env, FALSE);
env = ep;
}
/* fall through ... */
default:
escaped = FALSE;
}
}
if (ep > env) {
do_colon(env, FALSE);
}
}
/*
* Process the command line arguments.
*
* We can't really do this until we have run the "env" string,
* because "-s param=value" on the command line should override
* parameter setting in the environment.
*
* This is a bit awkward because it means usage() is called
* when we're already in vi mode (which means, among other
* things, that display pages may have been swapped).
*/
for (count = 1;
count < argc && (argv[count][0] == '-' || argv[count][0] == '+');
count++) {
if (argv[count][0] == '-') {
switch (argv[count][1]) {
case 't':
/*
* -t tag or -ttag
*/
if (numfiles != 0)
usage();
if (argv[count][2] != '\0') {
tag = &(argv[count][2]);
} else if (count < (argc - 1)) {
count += 1;
tag = argv[count];
} else {
usage();
}
break;
case 's':
/*
* -s param=value or
* -sparam=value
*/
if (argv[count][2] != '\0') {
argv[count] += 2;
} else if (count < (argc - 1)) {
count += 1;
} else {
usage();
}
do_set(curwin, 1, &argv[count], FALSE);
break;
default:
usage();
}
} else /* argv[count][0] == '+' */ {
char nc;
/*
* "+n file" or "+/pat file"
*/
if (count >= (argc - 1))
usage();
nc = argv[count][1];
if (nc == '/') {
pat = &(argv[count][2]);
} else if (is_digit(nc)) {
line = atol(&(argv[count][1]));
} else if (nc == '\0') {
line = 0;
} else {
usage();
}
count += 1;
files = &argv[count];
numfiles = 1;
}
}
if (numfiles != 0 || tag != NULL) {
/*
* If we found "-t tag", "+n file" or "+/pat file" on
* the command line, we don't want to see any more
* file names.
*/
if (count < argc)
usage();
} else {
/*
* Otherwise, file names are valid.
*/
numfiles = argc - count;
if (numfiles > 0) {
files = &(argv[count]);
}
}
/*
* Initialise the cursor and top of screen pointers
* to the start of the first buffer. Note that the
* bottom of screen pointer is also set up, as some
* code (e.g. move_window_to_cursor) depends on it.
*/
curwin->w_topline = curbuf->b_file;
curwin->w_botline = curbuf->b_file->l_next;
move_cursor(curwin, curbuf->b_file, 0);
curwin->w_col = 0;
curwin->w_row = 0;
/*
* Clear the window.
*
* It doesn't make sense to do this until we have a value for
* Pn(P_colour).
*/
clear(curwin);
if (numfiles != 0) {
if (line < 0 && pat == NULL)
echo = e_CHARUPDATE | e_SHOWINFO;
do_next(curwin, numfiles, files, FALSE);
if (pat != NULL) {
echo = e_CHARUPDATE | e_SHOWINFO | e_REGERR | e_NOMATCH;
(void) dosearch(curwin, pat, '/');
} else if (line >= 0) {
echo = e_CHARUPDATE | e_SHOWINFO;
do_goto((line > 0) ? line : MAX_LIN